package com.hmall.trade.listener;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.hmall.api.client.PayClient;
import com.hmall.api.dto.PayOrderDTO;
import com.hmall.common.domain.po.Order;
import com.hmall.trade.constants.MQConstants;
import com.hmall.trade.service.IOrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;

@Component
@RequiredArgsConstructor
@Slf4j
public class OrderDelayMessageListener {

    private final IOrderService orderService;
    private final PayClient payClient;
    private final RedisTemplate<String,String> redisTemplate;


    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = MQConstants.DELAY_ORDER_QUEUE_NAME),
            exchange = @Exchange(name = MQConstants.DELAY_EXCHANGE_NAME, delayed = "true"),
            key = MQConstants.DELAY_ORDER_KEY
    ))
    public void listenOrderDelayMessage(Message message){
        String messageId = message.getMessageProperties().getMessageId();
        String bodyStr = new String(message.getBody(), StandardCharsets.UTF_8);
        Long orderId = Long.valueOf(bodyStr);

        String redisKey = "trade-service:listenOrderDelayMessage:" + messageId;
//        String hashKey = DigestUtils.md5DigestAsHex(redisKey.getBytes());
        BoundValueOperations<String, String> boundValueOperations = redisTemplate.boundValueOps(redisKey);
        String value = boundValueOperations.get();

        if (StrUtil.isEmpty(value)){
            log.info("【延迟订单处理】开始处理 orderId = {}, messageId = {}", orderId, messageId);
            if (ObjUtil.isNull(orderId)){
                return;
            }
            //查询订单
            Order order = orderService.getById(orderId);
            if (ObjUtil.isNull(order) || order.getStatus() != 1){
                return;
            }

            //未支付  查询pay支付状态
            PayOrderDTO payOrderDTO = payClient.queryPayOrderByBizOrderNo(orderId);
            if (payOrderDTO != null && payOrderDTO.getStatus() == 3){
                //支付成功 修改订单状态
                orderService.markOrderPaySuccess(orderId);
            } else {
                //未支付  取消订单  回复库存
                orderService.cancelOrder(orderId);
            }

            //设置过期时间  5-10分钟  解决缓存雪崩  同一时间同时集中过期  都打到数据库  设置5到10分钟 打散
            int cacheExpireTime = 300 + RandomUtil.randomInt(0,300);
            //存入redis
            boundValueOperations.set("processed",cacheExpireTime, TimeUnit.SECONDS);
        } else {
            log.info("【延迟订单处理】消息已处理，跳过，messageId = {}", messageId);
        }

    }
}
